﻿// This software is the confidential and proprietary information of NetBay.
// Such confidential information should not be disclosed.
// NetBay copyright(c) 2012

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Text;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Navigation;
using NetBay.Core.BusinessEntities;
using NetBay.Core.BusinessEntities.Historic;
using Rio.Applications.Web.Services;
using Rio.Framework.Pages.Context;
using Rio.Framework.Pages.Enums;
using Rio.Framework.Pages.Manager;
using Rio.Framework.WCFService;

namespace Rio.Framework.Pages.AppCode.ApplicationNavigation
{
    public class NavigationHelper
    {
        #region Events

        public event NavigatedEventHandler Navigated;
        public event NavigatingCancelEventHandler Navigating;
        public event NavigationFailedEventHandler NavigationFailed;
        public event NavigationStoppedEventHandler NavigationStopped;
        public event NavigatedEventHandler FolderLinkBuilded;

        #endregion

        #region Fields

        private static readonly NavigationHelper instance;
        private Frame _currentFrame;

        #endregion

        #region Properties

        public static NavigationHelper Instance
        {
            get { return instance; }
        }
        public string RedirectUrl { get; set; }

        private Frame CurrentFrame
        {
            get
            {
                if (_currentFrame == null)
                {
                    throw new Exception(
                        "The Frame was not initialized. This can be fixed by calling to 'NavigationService.InitializeFrame'");
                }

                return _currentFrame;
            }
        }

        #endregion

        #region Constructors

        static NavigationHelper()
        {
            instance = new NavigationHelper();
        }

        private NavigationHelper() { }

        #endregion

        public void InitializeFrame(Frame frame)
        {
            _currentFrame = frame;

            CurrentFrame.Navigated += CurrentFrameNavigated;
            CurrentFrame.Navigating += CurrentFrameNavigating;
            CurrentFrame.NavigationFailed += CurrentFrameNavigationFailed;
            CurrentFrame.NavigationStopped += CurrentFrameNavigationStopped;
        }

        private void CurrentFrameNavigationStopped(object sender, NavigationEventArgs e)
        {

        }

        private void CurrentFrameNavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            if (NavigationFailed != null)
            {
                NavigationFailed(this, e);
            }
        }

        private void CurrentFrameNavigating(object sender, NavigatingCancelEventArgs e)
        {
            if (!e.Uri.OriginalString.ToUpperInvariant().StartsWith("/LOGIN"))
            {
                if (LoginManager.Instance.CurrentUser == null)
                {
                    if(LoginManager.Instance.AuthenticationMethod == LoginDomainServiceEnums.AuthenticationMethod.SSO)
                    {
                        string ntmlAccount = GlobalWebContext.RioAppSettings["UserAccount"];
                        ntmlAccount = ntmlAccount.Substring(ntmlAccount.IndexOf(@"\") + 1,
                                                            ntmlAccount.Length - ntmlAccount.IndexOf(@"\") - 1);

                        LoginManager.Instance.LogUser(ntmlAccount, String.Empty);
                    }
                    else
                    {
                        BusinessEntitiesDomainContext ds = new BusinessEntitiesDomainContext();
                        var getCurrentUserQuery = ds.GetCurentUserQuery();
                        ds.Load(getCurrentUserQuery,
                                result =>
                                {
                                    if (!result.HasError && result.Entities != null && result.Entities.Count() > 0 && result.Entities.First().IsValid)
                                    {
                                         LoginManager.Instance.SetUser(result.Entities.First());
                                         LoginManager.Instance.OnAuthenticatedUser();
                                    }
                                    else
                                    {
                                        NavigateToLogin(e.Uri.OriginalString);
                                    }
                                },
                                null);
                    }
                }
            }

            if (Navigating != null)
            {
                Navigating(this, e);
            }
        }

        private void CurrentFrameNavigated(object sender, NavigationEventArgs e)
        {
            if (Navigated != null)
            {
                Navigated(this, e);
            }
        }

        public void NavigateToLogin(string redirectUrl = null)
        {
            RedirectUrl = redirectUrl;
            HtmlPage.Window.Navigate(LoginManager.Instance.LoginPageUri);
        }

        public void NavigateToUri(String uri)
        {
            CurrentFrame.Navigate(new Uri(uri, UriKind.Relative));
        }

        public void NavigateToApplication(ApplicationName applicationName)
        {
            if (applicationName != ApplicationName.RioManager)
            {
                if (IsManagerSource())
                {
                    string fullUri = HtmlPage.Document.DocumentUri.OriginalString;
                    string path = fullUri.Substring(0, fullUri.IndexOf(HtmlPage.Document.DocumentUri.LocalPath));

                    VariableDomainContext variableDomainContext = new VariableDomainContext();
                    variableDomainContext.GetAppDomainAppVirtualPath(delegate(InvokeOperation<string> str)
                                                                         {
                                                                             StringBuilder url = new StringBuilder(path);

                                                                             if (str.Value != "/")
                                                                             {
                                                                                 url.Append(str.Value);
                                                                             }

                                                                             url.Append("/Default.aspx");

                                                                             switch (applicationName)
                                                                             {
                                                                                 case ApplicationName.RioFlow:
                                                                                     url.Append("#/Flow");
                                                                                     break;
                                                                                 case ApplicationName.RioImport:
                                                                                     url.Append("#/Import");
                                                                                     break;
                                                                                 case ApplicationName.RioOffice:
                                                                                     url.Append("#/Home");
                                                                                     break;
                                                                                 case ApplicationName.RioSearch:
                                                                                     url.Append("#/Search");
                                                                                     break;
                                                                             }

                                                                             HtmlPage.Window.Navigate(
                                                                                 new Uri(url.ToString(),
                                                                                         UriKind.Absolute));
                                                                         },
                                                                     null);
                }
                else
                {
                    string applicationUri = String.Empty;

                    switch (applicationName)
                    {
                        case ApplicationName.RioFlow:
                            applicationUri = "/Flow";
                            break;
                        case ApplicationName.RioImport:
                            applicationUri = "/Import";
                            break;
                        case ApplicationName.RioOffice:
                            applicationUri = "/Home";
                            break;
                        case ApplicationName.RioSearch:
                            applicationUri = "/Search";
                            break;
                    }

                    NavigateToUri(applicationUri);
                }
            }
            else
            {
                string fullUri = HtmlPage.Document.DocumentUri.OriginalString;
                string path = fullUri.Substring(0, fullUri.IndexOf(HtmlPage.Document.DocumentUri.LocalPath));

                VariableDomainContext variableDomainContext = new VariableDomainContext();
                variableDomainContext.GetAppDomainAppVirtualPath(delegate(InvokeOperation<string> str)
                                                                     {
                                                                         StringBuilder url = new StringBuilder(path);

                                                                         if (str.Value != "/")
                                                                         {
                                                                             url.Append(str.Value);
                                                                         }

                                                                         url.Append(
                                                                             "/Rio.Manager.Application.MainPage.aspx");

                                                                         HtmlPage.Window.Navigate(new Uri(
                                                                                                      url.ToString(),
                                                                                                      UriKind.Absolute));
                                                                     },
                                                                 null);
            }
        }

        public void ClearRedirectUrl()
        {
            RedirectUrl = String.Empty;
        }

        public void GoBack()
        {
            CurrentFrame.GoBack();
        }

        public void GoForward()
        {
            CurrentFrame.GoForward();
        }

        public bool IsManagerSource()
        {
            return
                HtmlPage.Document.DocumentUri.OriginalString.ToLowerInvariant().Contains(
                    "rio.manager.application.mainpage.aspx");
        }

        #region Historic

        public void GetFolderLink(long organizationId,
                                  long folderTypeId,
                                  long folderId,
                                  string folderIdDoc,
                                  bool navigate = false)
        {
            string queryString = String.Format(
                "#/Search?o={0}&ft={1}&f={2}&fid={3}&action=consultation",
                organizationId,
                folderTypeId,
                folderId,
                folderIdDoc);

            string path = HtmlPage.Document.DocumentUri.AbsoluteUri.Replace(
                HtmlPage.Document.DocumentUri.LocalPath, String.Empty);

            if (!String.IsNullOrWhiteSpace(HtmlPage.Document.DocumentUri.Fragment))
            {
                path = path.Replace(HtmlPage.Document.DocumentUri.Fragment, String.Empty);
            }

            if (!String.IsNullOrWhiteSpace(HtmlPage.Document.DocumentUri.Query))
            {
                path = path.Replace(HtmlPage.Document.DocumentUri.Query, String.Empty);
            }

            VariableDomainContext variableDomainContext = new VariableDomainContext();
            variableDomainContext.GetAppDomainAppVirtualPath(delegate(InvokeOperation<string> str)
                                                                 {
                                                                     StringBuilder sb = new StringBuilder(
                                                                         String.Format(
                                                                             "/Default.aspx{0}", queryString));

                                                                     Uri generatedUri = str.Value == "/"
                                                                                            ? new Uri(path + sb,
                                                                                                      UriKind.Absolute)
                                                                                            : new Uri(
                                                                                                  path + str.Value + sb,
                                                                                                  UriKind.Absolute);

                                                                     if (!navigate)
                                                                     {
                                                                         if (FolderLinkBuilded != null)
                                                                         {
                                                                             FolderLinkBuilded(
                                                                                 this,
                                                                                 new NavigationEventArgs(null,
                                                                                                         generatedUri));
                                                                         }
                                                                     }
                                                                     else
                                                                     {
                                                                         HtmlPage.Window.Navigate(generatedUri);
                                                                     }
                                                                 }
                                                             ,
                                                             null);
        }

        public void GetSearcResultLink(long organizationId,
                                       long folderTypeId,
                                       List<HistoricIndex> index,
                                       bool navigate = false)
        {
            StringBuilder queryStringBuilder = new StringBuilder(String.Format(
                "#/Search?o={0}&ft={1}",
                organizationId,
                folderTypeId));

            for (int i = 0; i < index.Count; i++)
            {
                queryStringBuilder.AppendFormat("&{0}={1}", i + 1, HttpUtility.UrlEncode(index.ElementAt(i).IndexValue));
            }

            queryStringBuilder.Append("&action=search");

            string path = HtmlPage.Document.DocumentUri.AbsoluteUri.Replace(
                HtmlPage.Document.DocumentUri.LocalPath, String.Empty);

            if (!String.IsNullOrWhiteSpace(HtmlPage.Document.DocumentUri.Fragment))
            {
                path = path.Replace(HtmlPage.Document.DocumentUri.Fragment, String.Empty);
            }

            if (!String.IsNullOrWhiteSpace(HtmlPage.Document.DocumentUri.Query))
            {
                path = path.Replace(HtmlPage.Document.DocumentUri.Query, String.Empty);
            }

            VariableDomainContext variableDomainContext = new VariableDomainContext();
            variableDomainContext.GetAppDomainAppVirtualPath(delegate(InvokeOperation<string> str)
                                                                 {
                                                                     StringBuilder sb = new StringBuilder(
                                                                         String.Format(
                                                                             "/Default.aspx{0}", queryStringBuilder));

                                                                     Uri generatedUri = str.Value == "/"
                                                                                            ? new Uri(path + sb,
                                                                                                      UriKind.Absolute)
                                                                                            : new Uri(
                                                                                                  path + str.Value + sb,
                                                                                                  UriKind.Absolute);

                                                                     if (!navigate)
                                                                     {
                                                                         if (FolderLinkBuilded != null)
                                                                         {
                                                                             FolderLinkBuilded(
                                                                                 this,
                                                                                 new NavigationEventArgs(null,
                                                                                                         generatedUri));
                                                                         }
                                                                     }
                                                                     else
                                                                     {
                                                                         HtmlPage.Window.Navigate(generatedUri);
                                                                     }
                                                                 }
                                                             ,
                                                             null);
        }

        public void GetImportLink(long organizationId,
                                  long folderTypeId,
                                  List<HistoricIndex> index,
                                  bool navigate = false)
        {
            StringBuilder queryStringBuilder =
                new StringBuilder(String.Format("#/Import?o={0}&ft={1}", organizationId, folderTypeId));

            for (int i = 0; i < index.Count; i++)
            {
                queryStringBuilder.AppendFormat("&{0}={1}", i + 1, HttpUtility.UrlEncode(index.ElementAt(i).IndexValue));
            }

            string path = HtmlPage.Document.DocumentUri.AbsoluteUri.Replace(
                HtmlPage.Document.DocumentUri.LocalPath, String.Empty);

            if (!String.IsNullOrWhiteSpace(HtmlPage.Document.DocumentUri.Fragment))
            {
                path = path.Replace(HtmlPage.Document.DocumentUri.Fragment, String.Empty);
            }

            if (!String.IsNullOrWhiteSpace(HtmlPage.Document.DocumentUri.Query))
            {
                path = path.Replace(HtmlPage.Document.DocumentUri.Query, String.Empty);
            }

            VariableDomainContext variableDomainContext = new VariableDomainContext();
            variableDomainContext.GetAppDomainAppVirtualPath(delegate(InvokeOperation<string> str)
                                                                 {
                                                                     StringBuilder sb = new StringBuilder(
                                                                         String.Format(
                                                                             "/Default.aspx{0}", queryStringBuilder));

                                                                     Uri generatedUri = str.Value == "/"
                                                                                            ? new Uri(path + sb,
                                                                                                      UriKind.Absolute)
                                                                                            : new Uri(
                                                                                                  path + str.Value + sb,
                                                                                                  UriKind.Absolute);

                                                                     if (!navigate)
                                                                     {
                                                                         if (FolderLinkBuilded != null)
                                                                         {
                                                                             FolderLinkBuilded(
                                                                                 this,
                                                                                 new NavigationEventArgs(null,
                                                                                                         generatedUri));
                                                                         }
                                                                     }
                                                                     else
                                                                     {
                                                                         HtmlPage.Window.Navigate(generatedUri);
                                                                     }
                                                                 }
                                                             ,
                                                             null);
        }

        #endregion
    }
}